package io.kiki.sba.registry.server.metadata.resource;

import io.kiki.sba.registry.common.model.Node;
import io.kiki.sba.registry.common.model.console.PersistenceData;
import io.kiki.sba.registry.common.model.console.PersistenceDataBuilder;
import io.kiki.sba.registry.common.model.constants.ValueConstants;
import io.kiki.sba.registry.common.model.metaserver.ProvideDataChangeEvent;
import io.kiki.sba.registry.core.model.Result;
import io.kiki.sba.registry.server.metadata.cleaner.AppRevisionCleaner;
import io.kiki.sba.registry.server.metadata.cleaner.InterfaceAppsIndexCleaner;
import io.kiki.sba.registry.server.metadata.provide.data.DefaultProvideDataNotifier;
import io.kiki.sba.registry.server.metadata.provide.data.ProvideDataService;
import io.kiki.sba.registry.server.metadata.resource.filter.LeaderAwareRestController;
import io.kiki.sba.registry.store.jdbc.convertor.AppRevisionDomainConvertor;
import io.kiki.sba.registry.util.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.Arrays;
import java.util.HashSet;

@Path("metaCenter")
@LeaderAwareRestController
public class MetaCenterResource {

    private static final Logger logger = LoggerFactory.getLogger(MetaCenterResource.class);
    @Autowired
    ProvideDataService provideDataService;
    @Autowired
    DefaultProvideDataNotifier provideDataNotifier;
    @Autowired
    private InterfaceAppsIndexCleaner interfaceAppsIndexCleaner;
    @Autowired
    private AppRevisionCleaner appRevisionCleaner;

    @PUT
    @Path("interfaceAppsIndex/renew")
    @Produces(MediaType.APPLICATION_JSON)
    public Result interfaceAppsIndexRenew() {
        Result result = new Result();
        interfaceAppsIndexCleaner.startRenew();
        result.setSuccess(true);
        return result;
    }

    @PUT
    @Path("interfaceAppsIndex/clean")
    @Produces(MediaType.APPLICATION_JSON)
    public Result interfaceAppsIndexClean() {
        Result result = new Result();
        interfaceAppsIndexCleaner.startCleaner();
        result.setSuccess(true);
        return result;
    }

    @PUT
    @Path("appRevisionCleaner/switch")
    @Produces(MediaType.APPLICATION_JSON)
    public Result appRevisionCleanerEnable(@FormParam("enabled") boolean enabled) {
        Result result = new Result();
        try {
            appRevisionCleaner.setEnabled(enabled);
            result.setSuccess(true);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setMessage(e.getMessage());
        }
        return result;
    }

    @PUT
    @Path("interfaceAppsCleaner/switch")
    @Produces(MediaType.APPLICATION_JSON)
    public Result interfaceAppsCleanerEnable(@FormParam("enabled") boolean enabled) {
        Result result = new Result();
        try {
            interfaceAppsIndexCleaner.setEnabled(enabled);
            result.setSuccess(true);
        } catch (Exception e) {
            result.setSuccess(false);
            result.setMessage(e.getMessage());
        }
        return result;
    }

    MetaCenterResource setInterfaceAppsIndexCleaner(InterfaceAppsIndexCleaner cleaner) {
        interfaceAppsIndexCleaner = cleaner;
        return this;
    }

    @PUT
    @Path("appRevision/writeSwitch")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Result setAppRevisionWriteSwitch(AppRevisionDomainConvertor.EnableConfig enableConfig) {
        PersistenceData persistenceData = PersistenceDataBuilder.createPersistenceData(ValueConstants.APP_REVISION_WRITE_SWITCH_DATA_ID, JsonUtils.writeValueAsString(enableConfig));
        Result result = new Result();
        boolean ret;
        try {
            ret = provideDataService.saveProvideData(persistenceData);
            logger.info("app revision write switch {} to DB result {}", enableConfig, ret);
        } catch (Throwable e) {
            logger.error("app revision write switch {} to DB result error", enableConfig, e);
            result.setSuccess(false);
            result.setMessage(e.getMessage());
            return result;
        }
        if (ret) {
            ProvideDataChangeEvent provideDataChangeEvent = new ProvideDataChangeEvent(ValueConstants.APP_REVISION_WRITE_SWITCH_DATA_ID, persistenceData.getVersion(), new HashSet<>(Arrays.asList(Node.NodeType.client_interface)));
            provideDataNotifier.notifyProvideDataChange(provideDataChangeEvent);
        }
        result.setSuccess(ret);
        return result;
    }


    public MetaCenterResource setProvideDataNotifier(DefaultProvideDataNotifier provideDataNotifier) {
        this.provideDataNotifier = provideDataNotifier;
        return this;
    }


    public MetaCenterResource setProvideDataService(ProvideDataService provideDataService) {
        this.provideDataService = provideDataService;
        return this;
    }


    public void setAppRevisionCleaner(AppRevisionCleaner appRevisionCleaner) {
        this.appRevisionCleaner = appRevisionCleaner;
    }
}
